<script>
    /* 
1.v-if和v-for循环那个优先级更高，区别是什么
    v-for优先级高于v-if
    两者同级出现,每次渲染都会先执行循环在判断条件，无论如何循环都不可避免浪费性能
    避免出现这种情况，可在外层嵌套一层进行v-if判断，然后再内部进行v-for循环
    如果条件出现在循环内部，可通过计算属性提前过滤掉那些不需要显示的项，减少dom操作
2.vue中key值的作用
    1.index值不是一定不变的，如果不加key值的话，删除前面的项，后面的index可能变，也可能不变，比如截个定时器的时候会变，不加定时器不会变
    2.不加key的话，更新机制的进行diff的时候会全部比较，比如删除第一个的话，后面的元素其实都不一样，会一项一项的比较，然后全部元素替换，没有做到最小更新,而且里面传的值也会变，如果这个时候你要根据里面的值删除元素的话，就会出错，尤其是加了定时器之后
    3.所以这个key值对数据改变知乎的diff更新比较有很大的性能提升，或者说有了key和没有key是两种比较和更新机制
    4.使用v-for更新已渲染的元素列表时，默认采用旧地复用策略，会复用之前的元素，有的时候使用index来作为key值，其实不是特别推荐的，可能会发生变化，做好是时间戳加上一个自增的数字
    5.如果有key的话，就会根据key值去判断某个是否修改，重新渲染这一项
    6.虚拟dom的diff算法：两个相同组件产生类似的dom结构，不同的组件产生不同的dom结构
                        同一层级的一组节点，可以通过唯一的id进行区分
                        当一层有很多相同的节点的时候，也就是列表节点时，diff算法的更新过程默认情况是遵循以上原则
                        如果数据的顺序被改变，Vue将不会移动DOM元素在匹配数据项的顺序，而是就地更新的策略
    7.就地复用的弊端
    虽然很高效，但是只适合与不依赖子组件状态或者临时的dom
    一旦要求新加入元素的状态，就会出问题
    总结：key的作用是用来对比组件自身新旧dom进行更新的跟踪节点的身份
         key的作用是辅佐判断新旧vdom节点在逻辑上是不是同一对象
         默认行为性能上会有提升？建议尽可能在使用v-for提供attribute，除非遍历输出的dom内容非常简单，或者是可以依赖默认行为以获取性能上的提升

3.ajax和axios和fetch的区别
    $.ajax({
        type:'POST',
        url:url,
        data:data,
        dataType:dataType,
        success:function(){},
        error:function(){}
    });
    传统Ajax指的是XMLHttpRequest(XHR),最早出现的发送后端请求技术，隶属于原始js中，核心使用XMLHttpRequest对象，多个请求之间如果有先回关系的话，就会出现回调地狱，Jquery ajax是对原生XHR的封装，除此以外还增添了对JSONP的支持，经过多年的更新维护，真的已经是非常的方便，缺点：
    1.本身是针对MVC的编程,不符合现在前端MVVM的浪潮
    2.基于原生的XHR开发，XHR本身的架构不清晰
    3.Jquery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理，采取个性化打包的方案又不能享受CDN服务
    4.不符合关注分离(Separation of Concents)的原则
    5.配置和调用方式非常混乱，而且基于事件的异步模型不友好
    ps：MVVM(Model-View-ViewModel)源自于经典的Model-View-Controller(MVC)模式，MVVM的出现促进了GUI前端开发与后端业务逻辑的分离，极大地提高了前端开发效率，MVVM的核心是ViewModel层，它就是一个中转站(value converter),负责转换Model中的数据对象来让数据变得更容易管理和使用，该层向上与视图层进行双向数据绑定，向下与Model层通过接口请求进行数据交互，起承上启下作用，View层展现的不是Model层的数据,而是ViewModel的数据，由ViewModel的负责与Model层交互，这就完全解耦了View和MOdel层，这个解耦是至关重要的，它是前后端分离方案实施的最重要的一环。
    axios({
        method:'post',
        url:'/uer/12345',
        data:{
            firstName:'fred',
            lastName:'Flintstone'
        }
    }).then(function(response){
        console.log(response)
    }).catch(function(error){
        console.log(error);
    })
    axios是一个基于Promise用于浏览器和nodejs的HTTP客户端，本质上也是对原生XHR的封装，只不过它是Promise的实现版本，符合最新的ES规范，它本身具有以下特征
    1.从浏览器中创建XMLHttpRequest
    2.支持Promise API
    3.客户端支持防止CSRF
    4.提供了一些并发请求的接口(方便了很多的操作)
    5.从node.js创建了http请求
    6.拦截请求和响应
    7.转换请求和响应数据
    8.取消请求
    9.自动转换JSON数据
    ps：防止CSRF：就是让你的每个请求都带一个从cookie中拿到的key根据浏览器同源，假冒的网址是拿不到你的cookie中得到key的，这样后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入，从而采取正确的策略。
    fetch 
        try {
            let response = await fetch(url);
            let data = response.json();
            console.log(data);
        } catch(e){
            console.log('Oops,error',e);
        }
    符合关注分离，没有将输入，输出和用事件来跟踪的状态混杂在一个对象里
    更好更方便的写法
    语法简单，更加语义化，基于标准Promise实现，支持async/await
    同构方便，使用[isomprophic-fetch]
    更加底层，提供的API丰富(request,response)
    脱离了XHR，是ES规范里新的实现方式
    缺点：fetch只对网络请求报错，对于400,500都当作成功的请求，服务器返回400，500的错误码并不会reject，
        fetch默认不会带cookie，需要添加配置项：fetch(url,{credentials:'include'})
        fetch不支持abort，不支持超时控制，使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求
        fetch没有办法原发监测请求的进度，而XHR可以
4.button的属性
     autofocus:按钮获得焦点，值为autofocus   
     disabled：禁用该按钮值为disabled;
     form:关联一个或多个表单，值为：表单的id属性值
     formaction：提交表单时向何处发送表单数据，将覆盖form标签中的action属性，需要type=‘submit’配合使用
     formenctype：向服务器发送表单数据之前如何对其进行编码，将覆盖form表单中的enctype属性，需与type="submit"配合使用，只可以是：multipart/form-data、text/plain等；
    formmethod：用于发送表单数据的HTTP方法，将覆盖form标签中的method属性，需与type="submit"配合使用，值可以是：get、post；
    formnovalidate：规定提交表单时不进行验证，将覆盖form标签中的novalidate属性，需与type="submit"配合使用，值为：formnovalidate；
    formtarget：规定在何处打开目标，将覆盖form标签中的target属性，需与type="submit"配合使用，值可以为：_blank、_self、_parent、_top、framename；
    name：按钮的名称，值为：自定义；
    type：按钮的类型，只可以是：button、reset、submit；
    value：按钮的初始值，值为：自定义
5.vue和vuex的通信
    Vuex是一个专为Vue.js应用程序开发的状态管理模式，它采用集中式存储管理应用的所有组件的状态，并以相应的规则保证转态以一种可预测的方式发生变化
    vue是一个渐进式框架
6.输入url到看到页面发生了什么
    1.DNS解析 
    2.发起TCP连接
    3.发送http请求
    4.服务器处理请求并返回HTTP报文
    5.浏览器解析渲染页面
    6.连接结束
7.position中的属性和清除浮动
    static静态属于正常的流
    fixed 固定相对于整个页面定位
    stiky：粘性，在页面原型时为absolute，页面下滑或其他溢出看不到元素时，变为fixed
    absolute:相对于第一个父元素定位
    relative：相对于本身定位

    清除浮动：使用clear属性的空元素
            使用css的overflow属性
            给浮动的元素添加浮动
            使用css的after伪元素
8.nodejs操作
9.vue的特性
    1.轻量级的框架：Vue.js能够自动追踪依赖的模板表达式和计算属性，提供MVVM数据绑定和一个可组合的组件系统，具有简单，灵活的API，是读者更加容易理解，能更快上手
    2.双向数据绑定：声明式渲染时数据双向绑定的主要体现，同样也是Vue.js的核心，它允许采用简洁的模板语法将数据声明式渲染整合进DOM
    3.指令 Vue.js与页面进行交互，主要是通过内置指令来完成的，指令的作用是当其表达式的值改变时相应地将某些应用到DOM上
    4.组件化：组件(Component)是Vue.js是强大的功能之一，组件可以扩展HTML元素，封装可重用的代码
    在Vue中父子组件通过props传递通信，从父向子单向传递，子组件与父组件通信，通过触发事件通知父组件改变数据，这样就形成了一个基本的父子组件通信模式
    在开发中组件和HTML，JavaScript等有非常紧密的关系时，可以根据实际的需要自定义组件，使开发变得更加便利，可大量减少代码编写量
    组件还支持热重载（hotreload）当我们做了修改时，不会刷新页面，只是对组件本身进行立刻重载不会影响整个应用当前的状态，css也支持热重载
    5.客户端路由：Vue-router是Vue.js官方的路由插件，与Vue.js深度集成，用于构建单页面应用。Vue单页面应用是基于路由和组件的，路由用于设定访问路径，并
    将路径和组件映射起来，传统的页面是通过超链接实现页面的切换和跳转的
    6状态管理:状态管理实际就是一个单向的数据流，state驱动View的渲染，而用户对View进行操作产生Action，使State产生变化，从而使View重新渲染，形成一个单独的组件

10.提高性能优化
    合并文件，减少https请求，精灵图 减少DNS查找次数DNS缓存
    
11.选择器之间
    !import 在属性后面写上这条样式，会覆盖掉页面上任何位置定义的元素的样式
    行内样式，在style属性里面写的样式
    id选择器
    class选择器
    标签选择器
    通配符选择器
    浏览器的自定义属性和继承

12.call apply bind
    call：把找到call方法执行，当call方法执行的时候，内部处理了一些事情
    首先把要操作的函数中的this关键字变为call方法第一个传递的实参，2.把call方法第二个及之后的实参获取到
    3.把要操作的函数执行，并且把第二个以后传递进来的实参传递给函数
    apply传参时一个数组
    bind区别在于立即执行，还是等待执行
13.flex
        flex-direction
        flex-wrap
        flex-flow
        justify-content
        align-items
        align-context
14.溢出隐藏的属性
    white-space：nowrap；
    text-overflow：ellipsis
    overflow:hidden
    多行文本溢出
        overflow：hidden
        text-overflow：ellipsis
        display： -webkit-box
        webkit-line-clamp：2数字是几，就是几行溢出隐藏
        webkit-box-orient：vertical
15.水平垂直居中的方式
    绝对定位方法：不确定当前div的宽度和高度，采用transform：translate（-50%；-50%）当前父级添加相对定位position：relactive
    绝对定位方法：确定了当前div的宽度，margin值为当前div宽度一半的负值  
    　绝对定位方法：绝对定位下top left right bottom 都设置0
    flex垂直居中
    table：cell
16.watch和computer的区别
    computed是计算属性：事实上和data对象里的数据属性是同一类的（使用上）
    watch类似于监听机制+事件机制
    1.watch擅长处理的场景：一个数据影响多个数据 watch属性是一个对象，键是需要观察的表达式，值是对应回调函数，回调函数得到的参数为新值和旧值。值也可以是方法名，或者包含选项的对象。侦察器对于任何更新的东西都有用——无论是表单输入、异步更新还是动画。vue实例在实例化时调用$watch()，遍历watch对象的每一个属性。
    2.computed擅长处理的场景：一个数据受多个数据影响 计算属性是根据依赖关系进行缓存的计算，并且只在需要的时候进行更新。
17.vue3和vue2的区别
    1.重构响应式系统,使用Proxy替换Object.defineProperty,使用Proxy优势
    可直接监听数组类型的数据变化
    监听的目标为对象本身，不需要像Object.defineProperty一样遍历每个属性，有一定的性能提升
    可拦截apply，ownKeys，has等13种方法，而Object.defineProperty不行
    直接实现对象属性的新增/删除
    2.新增Composition API，更好的逻辑复用和代码组织
        为什么要新增Composition，组件变得越来越复杂，越来越难维护而难以维护的根本原因是vue的API设计迫使开发者使用watch，computed。methods选项组织
        代码,而不是实际的业务逻辑
        另外Vue2.0缺少了较为简洁的低成本的机制来完成逻辑复用，虽然可以mixis完成逻辑复用，但是当mixin变多的时候，会使得难以找到对应的data，computed或者method来源于那个mixin，使得类型推断难以进行
        所以Composition API的出新，主要也是为了解决Option API带来的问题，第一个是代码组织问题，Composition API可以让开发者根据业务逻辑组织自己的代码，让代码
        具备更好的可读性和可扩展性，也就是说当下一个开发者接触这一段不是他自己写的代码时，他可以更好的利益代码的组织反推出实际的业务逻辑，或者根据业务逻辑更好的理解代码
        第二个是实现代码的逻辑提取与复用，当然mixin也可以实现逻辑提取与复用，但是像前面所说的，多个mixin作用在同一个组件时，很难看出property是来源于那个mixin。来源不清楚，另外，多个mixin的property存在变量命名冲突的风险。
        而Composition API刚好解决了这两个问题
    3.重构Virtual DOM
    模板编译时的优化,将一些静态节点编译成常量
    slot优化，将slot编译为lazy函数，将slot的渲染的决定权交给子组件
    模板中内联事件的提取并重用(原本每次渲染都重新生成内联函数)
    4.代码结构调整，更便于Tree shaking，使得体积更小
    5.使用Typescript替换Flow
    


18.闭包的优缺点
闭包：能够读取其他函数内部变量的函数。（应用场景：要获取某函数内部的局部变量）
闭包的优点：1.能够读取函数内部的变量 2.让这些变量一直存在于内存中，不会在调用结束后，被垃圾回收机制回收
闭包的缺点：正所谓物极必反，由于闭包会使函数中的变量保存在内存中，内存消耗很大，所以不能滥用闭包，解决办法是，退出函数之前，将不使用的局部变量删除。
19.浏览器引擎常用浏览器引擎

20宏任务和微任务
宏任务：setTimeout setInterval setImmediate 浏览器执行的
微任务：process.nextTick muationObserve Promise.then.catch .finally js引擎执行的
promise的三个属性pending fulfilled（成功调用resolve） reject(失败) Promise解决回调地狱
21继承
1.原型链继承
2.借用构造函数继承
3.组合式继承
4.原型式继承
5.寄生式继承
6.寄生组合式继承

22.rem
 1rem等于16px，rem通过根元素进行适配的，网页中的根元素是html我们通过设置html的字体大小就可以控制rem的大小
23.浏览器的引擎
 Trindet内核（IE） Gecko（火狐） WEbkit（谷歌） Presto（opera）
 渲染引擎和js引擎
 24.深拷贝和浅拷贝
 object.assgin() 递归
 23.递归实现1-100的和
    自己调用自己本身
    function sum(num) {
    if( num==1 ){
        return 1;
        }
    return num+sum(num-1);
    }
 24.
    */
</script>